Skip to content

feat: CSF Factories (CSF Next) support#826

Open
dannyhw wants to merge 17 commits intonextfrom
dannyhw/feat/csf-factories
Open

feat: CSF Factories (CSF Next) support#826
dannyhw wants to merge 17 commits intonextfrom
dannyhw/feat/csf-factories

Conversation

@dannyhw
Copy link
Member

@dannyhw dannyhw commented Dec 15, 2025

Summary

Adds support for CSF Next, the new Storybook configuration and story authoring format available experimentally in Storybook 10.

CSF Next replaces the traditional export default meta / export const Story pattern with a definePreview() / defineMain() / meta.story() API that provides full type safety, composability, and better IDE support.

Core changes

  • definePreview() support — Re-exports definePreview from @storybook/react and adds resolveAnnotations() in Start.tsx to unwrap the opaque Preview object that definePreview() produces. We extract .input (the user's plain config) rather than using .composed, which includes web-specific core annotations that depend on a browser environment not available on-device.
  • defineMain() support — Adds a typed defineMain() helper exported from @storybook/react-native/node for type-safe main config.
  • StorybookConfig type refinement — Moved to types/config.ts, now uses Preset type for addons instead of loose string/object union.
  • Improved type annotations — Replaces any[] with ModuleExports[] and unknown throughout Start.tsx.

Examples and tests

  • Adds .factories.stories.tsx variants for all existing example stories demonstrating the factories API
  • Adds .factories.test.tsx portable story tests for factories stories
  • Adds .rnstorybook-nofactories/ config directory to test both config styles side-by-side
  • Updates metro.config.js and App.tsx to support switching between factories and non-factories configs

How the factories API looks

preview.tsx (before):

import type { Preview } from '@storybook/react-native';

const preview: Preview = {
  parameters: { /* ... */ },
};
export default preview;

preview.tsx (after):

import { definePreview } from '@storybook/react-native';

export default definePreview({
  addons: [],
  parameters: { /* ... */ },
});

Stories (before):

const meta = { component: Button } satisfies Meta<typeof Button>;
export default meta;
export const Primary: StoryObj<typeof meta> = { args: { label: 'Click' } };

Stories (after):

const meta = config.meta({ component: Button });
export const Primary = meta.story({ args: { label: 'Click' } });

Test plan

  • pnpm build completes successfully
  • pnpm test passes — both factories and non-factories story tests
  • Run expo example with factories config — stories render correctly
  • Run expo example with non-factories config — stories render correctly
  • definePreview() config is properly unwrapped (parameters, decorators, etc. are applied)
  • defineMain() provides type checking for main config

@changeset-bot
Copy link

changeset-bot bot commented Feb 27, 2026

⚠️ No Changeset found

Latest commit: 5ac5bb1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

…andling

Add storybook as devDependency to all workspace packages so pnpm hoists
a single copy, fixing duplicate action events caused by two separate
module instances each registering their own listener.

Sanitize RN synthetic events in action payloads only on the WebSocket
channel where async transport causes event pool recycling. Remove the
unnecessary patch from the local sync channel.

Remove early-return guards from addon panels so hooks are called
unconditionally, fixing React rules-of-hooks violations.
- Changed annotations parameter type from any[] to ModuleExports[] in resolveAnnotations and getProjectAnnotations functions.
- Introduced a PreviewObject interface and isPreviewObject type guard for better handling of preview objects.
- Updated storyEntries type to use Record<string, unknown> instead of any for improved type clarity.
@dannyhw dannyhw marked this pull request as ready for review February 27, 2026 22:16
@dannyhw dannyhw changed the title feat: csf factories feat: csf next support Feb 27, 2026
- Updated storyEntries and normalizedStories types to use unknown instead of Record<string, unknown> for improved type flexibility.
- Added '@storybook/react-native-theming' as a dependency for theming capabilities.
- Updated ActionLogger to use styled components for count text based on the current theme.
- Refactored Inspect component to utilize themed text styles for various data types, enhancing visual consistency and readability.
@dannyhw dannyhw changed the title feat: csf next support feat: CSF Factories (CSF Next) support Feb 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant